//
// ReflectionFu.cs
//
// Copyright (c) 2007 Lukas Lipka.
//

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace IcqSharp.Util
{
    class ReflectionFu
    {
        public static List<Type> ScanAssemblyForTypes (Type type)
        {
            Assembly assembly = Assembly.GetExecutingAssembly ();

            List<Type> types = new List<Type> ();

            foreach (Type t in assembly.GetTypes ()) {
                if (t.IsSubclassOf (type))
                    types.Add (t);
            }

            return types;
        }

        public static List<Type> ScanAssemblyForInterfaces(Type type)
        {
            Assembly assembly = Assembly.GetExecutingAssembly ();

            List<Type> types = new List<Type> ();

            foreach (Type t in assembly.GetTypes())
            {
                Type[] interfaces = t.GetInterfaces();

                foreach (Type i in interfaces)
                {
                    if (i == type)
                        types.Add(t);
                }
            }

            return types;
        }

        public static Attribute ScanTypeForAttribute (Type type, Type custom_attribute)
        {
            object[] attributes = Attribute.GetCustomAttributes(type);

            foreach (object attribute in attributes) {
                Type attribute_type = attribute.GetType ();

                if (attribute_type == custom_attribute || attribute_type.IsSubclassOf(custom_attribute))
                    return (Attribute)attribute;
            }

            return null;
        }

        public static object CreateInstance (Type type, params object[] args)
        {
            Type[] types = new Type[args.Length];

            for(int i = 0; i < args.Length; i++)
                types [i] = args [i].GetType ();

            ConstructorInfo info = type.GetConstructor (types);
            return info.Invoke (args);
        }
    }
}
